package com.xteam.utils;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

final public class DBTools {

	private DBTools() {
	}

	public static Map<String, Object> createSingleObject(ResultSet rs) throws SQLException {
		Map<String, Object> entity = new HashMap<String, Object>();
		packageObject(rs, entity);
		return entity;
	}

	public static void packageObject(ResultSet rs, Map<String, Object> entity) throws SQLException {
		String[] columns = getColumnNames(rs.getMetaData());
		if (rs.next()) {
			for (String column : columns) {
				entity.put(column, rs.getObject(column));
			}
		}
	}

	public static String[] createPrimaryKeyArray(ResultSet rs, Map<String, Object> entity, String columnName) throws SQLException {
		String[] columns = getColumnNames(rs.getMetaData());
		List<String> pks = new ArrayList<String>();
		if (rs.next()) {
			for (String column : columns) {
				Object o = rs.getObject(column);
				if (columnName.equals(column)) {
					if (!(o instanceof String))
						throw new ClassCastException("主键不是字符串类型");
					pks.add((String) o);
				}
				entity.put(column, o);
			}
		}
		return pks.toArray(new String[pks.size()]);
	}

	public static List<Map<String, Object>> createArrayObject(ResultSet rs) throws SQLException {
		List<Map<String, Object>> entity = new ArrayList<Map<String, Object>>();
		packageArrayObject(rs, entity);
		return entity;
	}

	public static void packageArrayObject(ResultSet rs, List<Map<String, Object>> entity) throws SQLException {
		packageArrayObject(rs, entity, false);
	}

	public static void packageArrayObject(ResultSet rs, List<Map<String, Object>> entity, boolean blag) throws SQLException {
		String[] columns = getColumnNames(rs.getMetaData());
		boolean flag = false;
		while (rs.next()) {
			flag = true;
			Map<String, Object> o = new HashMap<String, Object>();
			for (String column : columns) {
				o.put(column, rs.getObject(column));
			}
			entity.add(o);
		}
		if (blag == true) {
			if (flag == false) {
				entity.add(new HashMap<String, Object>());
			}
		}
	}

	public static String[] createPrimaryKeyArray2(ResultSet rs, List<Object> entity, String columnName) throws SQLException {
		String[] columns = getColumnNames(rs.getMetaData());
		List<String> pks = new ArrayList<String>();
		while (rs.next()) {
			Map<String, Object> m = new HashMap<String, Object>();
			for (String column : columns) {
				Object o = rs.getObject(column);
				if (columnName.equals(column)) {
					if (!(o instanceof String))
						throw new ClassCastException("主键不是字符串类型");
					pks.add((String) o);
				}
				m.put(column, o);
			}

			entity.add(m);
		}
		return pks.toArray(new String[pks.size()]);
	}

	public static String[] createPrimaryKeyArray(ResultSet rs, List<Map<String, Object>> entity, String columnName) throws SQLException {
		String[] columns = getColumnNames(rs.getMetaData());
		List<String> pks = new ArrayList<String>();
		while (rs.next()) {
			Map<String, Object> m = new HashMap<String, Object>();
			for (String column : columns) {
				Object o = rs.getObject(column);
				if (columnName.equals(column)) {
					if (!(o instanceof String))
						throw new ClassCastException("主键不是字符串类型");
					pks.add((String) o);
				}
				m.put(column, o);
			}
			entity.add(m);
		}
		return pks.toArray(new String[pks.size()]);
	}

	public static String[] findPrimaryKeyToArray(ResultSet rs) throws SQLException {
		String[] columns = getColumnNames(rs.getMetaData());
		List<String> pks = new ArrayList<String>();
		while (rs.next()) {
			for (String column : columns) {
				Object o = rs.getObject(column);
				if (!(o instanceof String))
					throw new ClassCastException("主键不是字符串类型");
				pks.add((String) o);
			}
		}
		return pks.toArray(new String[pks.size()]);
	}

	public static String[] getColumnNames(ResultSetMetaData meta) throws SQLException {
		int size = meta.getColumnCount();
		String[] columnNames = new String[size];
		for (int i = 0; i < size; i++) {
			String columnName = meta.getColumnLabel(i + 1);
			if (null == columnName)
				columnName = meta.getColumnName(i + 1);
			columnNames[i] = columnName;
		}
		return columnNames;
	}

	public static void closePreparedStatement(PreparedStatement prepared) throws SQLException {
		if (null != prepared)
			prepared.close();
	}

	public final static Object typeMapping(String dbType, Object value) {
		dbType = dbType.toLowerCase();
		if ("int".equals(dbType)) {
			return java.lang.Integer.valueOf(String.valueOf(value));
		} else if ("time".equals(dbType)) {
			return java.sql.Time.valueOf(String.valueOf(value));
		} else if ("date".equals(dbType)) {
			return java.sql.Date.valueOf(String.valueOf(value));
		} else if ("datetime".equals(dbType)) {
			return java.sql.Timestamp.valueOf(String.valueOf(value));
		} else if ("varchar".equals(dbType)) {
			return String.valueOf(value);
		}
		throw new AssertionError("未找到数据库类型映射！");
	}

	public enum DBType {
		/**
		 * 字符串
		 */
		VARCHAR("字符串文本", String.class, true),
		/**
		 * 日期
		 */
		DATE("日期", Date.class, false),
		/**
		 * 日期时间
		 */
		DATETIME("日期时间", Timestamp.class, false),
		/**
		 * 复选框
		 */
		TINYINT("复选框", Short.class, false),
		/**
		 * 时间
		 */
		TIME("时间", Date.class, false),
		/**
		 * 数值
		 */
		INT("数值", Integer.class, false);

		final String	text;
		final Class<?>	clazz;
		final boolean	isLength;

		DBType(String text, Class<?> clazz, boolean isLength) {
			this.text = text;
			this.clazz = clazz;
			this.isLength = isLength;
		}

		public String getText() {
			return text;
		}

		public boolean isLength() {
			return isLength;
		}

		public Class<?> getClazz() {
			return clazz;
		}

		public static DBType getType(String text) {
			DBType[] types = DBType.values();
			for (DBType type : types) {
				if (type.text.equals(text)) {
					return type;
				}
			}
			throw new NullPointerException("未找到匹配的类型");
		}
	}
}
